#include <iostream>
#include <sstream>
#include "send_helper.h"

#include "packet_base.h"
#include "cmd.h"
#include "common.h"
#include "log.h"
#include "app.h"

#include "attributes/common.pb.h"
#include "attributes/player.pb.h"
#include "attributes/scene.pb.h"
#include "attributes/combat.pb.h"

#include "service/account_service.pb.h"
#include "service/common_service.pb.h"
#include "service/scene_service.pb.h"
#include "service/player_service.pb.h"


#include <sys/types.h>
#include <sys/socket.h>

SendHelper::SendHelper(/* args */)
{
}

SendHelper::~SendHelper()
{
}

void SendHelper::Init(){
    cmd2func_.emplace(cmd::CLIENT_LOGIN, std::bind(&SendHelper::Login, this, cmd::CLIENT_LOGIN));
    // cmd2func_.emplace(cmd::CLIENT_ENTER, std::bind(&SendHelper::EnterScene, this, cmd::CLIENT_ENTER));
    // cmd2func_.emplace(cmd::CLIENT_LEAVE, std::bind(&SendHelper::LeaveScene, this, cmd::CLIENT_LEAVE));
    cmd2func_.emplace(cmd::CLIENT_LOGOUT, std::bind(&SendHelper::Logout, this, cmd::CLIENT_LOGOUT));
    cmd2func_.emplace(cmd::CLIENT_GET_PLAYER_INFO, std::bind(&SendHelper::GetPlayerInfo, this, cmd::CLIENT_GET_PLAYER_INFO));
    cmd2func_.emplace(cmd::CLIENT_ENTER_DEFAULT_SCENE, std::bind(&SendHelper::RequestEnterDefaultScene, this, cmd::CLIENT_ENTER_DEFAULT_SCENE));
    cmd2func_.emplace(cmd::CLIENT_MOVE, std::bind(&SendHelper::RequestMove, this, cmd::CLIENT_MOVE));
    cmd2func_.emplace(cmd::CLIENT_USE_SKILL, std::bind(&SendHelper::RequestUseSkill, this, cmd::CLIENT_USE_SKILL));

    // cmd2func_.emplace(cmd::CLIENT_MOVE, std::bind(&SendHelper::StartMove, this, cmd::CLIENT_MOVE));
    // cmd2func_.emplace(cmd::CLIENT_STOP_MOVE, std::bind(&SendHelper::StopMove, this, cmd::CLIENT_STOP_MOVE));
}

bool SendHelper::CheckCmd(int cmd_id){
    return cmd2func_.find(cmd_id) != cmd2func_.end();
}

void SendHelper::ListCmds(){
    std::cout << "输入0查看指令列表" << std::endl;
    for(auto v: cmd::cmd_id_desc){
        std::cout << v << std::endl;
    }
}

void SendHelper::Process(int cmd_id, int& fd){
    if(fd < 0){
        return;
    }

    if(cmd_id == 0){
        ListCmds();
        return;
    }

    if(!CheckCmd(cmd_id)){
        std::cout << "指令错误：" << cmd_id << std::endl;
        return;
    }

    auto func = cmd2func_[cmd_id];
    std::string buff = func();
    // if(buff.compare("") == 0){
    //     return;
    // }

    PacketBase pack;
    pack.Begin(cmd_id);
    pack.Write(buff.c_str(), buff.length());
    pack.End();

    LOG_DEBUG("buff size:{}", pack.GetBufferSize());
    ssize_t ret = ::send(fd, pack.GetOriginBuffer(), pack.GetBufferSize(), 0);

    if(ret > 0){
        LOG_DEBUG("发送成功:{}", ret);
    }else{
        LOG_ERR("发送失败 ret:{} errno:{}", ret, errno);
        ::close(fd);
        fd = -1;
    }
}

std::string SendHelper::Login(int cmd_id){
    LOG_DEBUG("Login cmd_id:{}", cmd_id);
    std::cout << "请输入账号" << std::endl;
    char username[common::MAXLINE];
    std::cin >> username;

    std::cout << "请输入密码" << std::endl;
    char password[common::MAXLINE];
    std::cin >> password;

    service::account::LoginRequest login_request;
    login_request.set_username(username);
    login_request.set_password(password);

    // 编码
    return login_request.SerializeAsString();
}

std::string SendHelper::Logout(int cmd_id){
    LOG_DEBUG("Login cmd_id:{}", cmd_id);
    return "";
}

std::string SendHelper::GetPlayerInfo(int cmd_id){
    LOG_DEBUG("Login cmd_id:{}", cmd_id);
    service::player::GetPlayerBaseInfoRequest request;
    request.set_uid(App::GetIns().GetMainPlayer()->GetPlayerID());
    return request.SerializeAsString();
}

std::string SendHelper::RequestEnterDefaultScene(int cmd_id){
    LOG_DEBUG("Login cmd_id:{}", cmd_id);
    service::scene::RequestEnterDefaultScene request;
    return request.SerializeAsString();
}

std::string SendHelper::RequestMove(int cmd_id){
    return StartMove(cmd_id);
}

std::string SendHelper::RequestUseSkill(int cmd_id){
    std::cout << "请输入技能ID:";
    std::string input;
    int val;
    std::getline(std::cin, input);
    std::stringstream ss(input);
    if(ss >> val && ss.eof()){
        if(val <= 0){
            std::cout << "技能ID需要大于0" << std::endl;
            return "";
        }

        service::scene::RequestUseSkill skill;
        skill.set_skill_id(val);
        return skill.SerializeAsString();
    }else{
        std::cout << "技能ID输入错误" << std::endl;
        return "";
    }
}

// std::string SendHelper::EnterScene(int cmd_id){
//     LOG_DEBUG("EnterScene cmd_id:{}", cmd_id);
//     scene::EnterScene enter_scene;
//     enter_scene.set_cmd("enter");
//     return enter_scene.SerializeAsString();
// }

// std::string SendHelper::LeaveScene(int cmd_id){
//     LOG_DEBUG("LeaveScene cmd_id:{}", cmd_id);
//     scene::LeaveScene leave_scene;
//     leave_scene.set_cmd("leave");
//     return leave_scene.SerializeAsString();
// }

std::string SendHelper::StartMove(int cmd_id){
    LOG_DEBUG("StartMove cmd_id:{}", cmd_id);
    std::cout << "移动方向: 1向上, 2向下, 3向左, 4向右, 0停止" << std::endl;
    std::cout << "请输入移动方向:";

    std::string input;
    int val;
    std::getline(std::cin, input);
    std::stringstream ss(input);
    if(ss >> val && ss.eof()){
        if(val < EDirection::DIRECTION_START || val >= EDirection::DIRECTION_END){
            std::cout << "方向输入错误" << std::endl;
            return "";
        }

        service::scene::RequestMove move;
        if(val == 0){
            move.set_direction(1);
            move.set_auto_move(false);
            move.set_stop_move(true);    
        }else{
            move.set_direction(val);
            move.set_auto_move(true);
            move.set_stop_move(false);
        }
        return move.SerializeAsString();
    }else{
        std::cout << "方向输入错误" << std::endl;
        return "";
    }
}

// std::string SendHelper::StopMove(int cmd_id){
//     LOG_DEBUG("StopMove cmd_id:{}", cmd_id);
//     scene::StopMove move;
//     move.set_cmd("stop_move");
//     return move.SerializeAsString();
// }
